package chen.yi.service.service.login;

import chen.yi.common.constant.RedisKeyConstant;
import chen.yi.common.constant.RedisTimeConstant;
import chen.yi.common.constant.TokenConstant;
import chen.yi.common.resp.R;
import chen.yi.common.utils.TokenUtils;
import chen.yi.component.redis.utils.RedisUtil;
import chen.yi.mapper.dto.login.LoginDTO;
import chen.yi.mapper.po.UserInfoPO;
import chen.yi.mapper.vo.login.CodeInfoVO;
import chen.yi.mapper.vo.login.LoginUserVO;
import chen.yi.service.service.user.UserInfoService;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.Objects;
import java.util.UUID;

/**
 * 登录业务层实现
 * @author huat
 **/
@Service
@Slf4j
public class LoginServiceImpl implements LoginService {

    private final UserInfoService userInfoService;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public LoginServiceImpl(UserInfoService userInfoService, PasswordEncoder passwordEncoder) {
        this.userInfoService = userInfoService;
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    public R<CodeInfoVO> getCode() {
        System.out.println(passwordEncoder.encode("HuaTao0221.."));
        //生成验证码标识
        String uuid = UUID.randomUUID().toString().replaceAll("-","");
        log.info("验证码标识符 uuid:【{}】", uuid);
        // 设置验证码的运算类型（加减乘除）
        // 创建MathCaptcha对象，指定宽度、高度、验证码长度、干扰线数量
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100,4,5);
        //获取验证码base64图片
        String codeBase64 = lineCaptcha.getImageBase64Data();
        //验证码放入redis
        RedisUtil.set(RedisKeyConstant.LOGIN_CODE+uuid, lineCaptcha.getCode(), RedisTimeConstant.CODE_TIME);
        CodeInfoVO codeInfoVO = new CodeInfoVO();
        codeInfoVO.setUuid(uuid);
        codeInfoVO.setCode(codeBase64);
        return R.success(codeInfoVO);
    }

    @Override
    public R<?> doLogin(LoginDTO loginDTO, HttpServletResponse response) {
        Object codeRedis = RedisUtil.get(RedisKeyConstant.LOGIN_CODE+loginDTO.getUuid());
        String codeUser = loginDTO.getCode();
        log.info("缓存中验证码:{} 用户输入验证码:{}", codeRedis, codeUser);
        if(Objects.isNull(codeRedis)||!StrUtil.equalsIgnoreCase(codeRedis.toString(), codeUser)){
            log.info("验证码错误");
            return R.error("验证码不正确");
        }
        String username = loginDTO.getUsername();
        UserInfoPO userInfo = userInfoService.getByUsername(username);
        log.info("用户名:{} 查询到的对象:{}", username, userInfo);
        if(Objects.isNull(userInfo)) {
            return R.error("用户名不存在");
        }
        if(!passwordEncoder.matches(loginDTO.getPassword(),userInfo.getPassword())) {
            log.info("密码错误");
            return R.error("密码错误");
        }
        LoginUserVO loginUserVO = BeanUtil.toBean(userInfo, LoginUserVO.class);
        Map<String, Object> userMap = BeanUtil.beanToMap(loginUserVO);
        String token = TokenUtils.createToken(userMap);
        log.info("token生成完成");
        response.setHeader(TokenConstant.TOKEN_KEY, token);
        response.setHeader("Access-Control-Expose-Headers",TokenConstant.TOKEN_KEY);
        userMap.put(TokenConstant.TOKEN_KEY, token);
        RedisUtil.set(RedisKeyConstant.LOGIN_USER+loginUserVO.getId(),userMap);
        return R.success(loginUserVO);
    }
}
